package hos.http;

import android.app.Activity;
import android.app.Dialog;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import hos.http.converter.HttpConvert;
import hos.http.retrofit.TypeUtil;

/**
 * <p>Title: HttpBaseRequest </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023/3/1 20:59
 */
public interface HttpBaseRequest<T extends HttpBaseRequest<T>> {

    T apply(HttpApply<T> httpApply);

    T dialog(boolean showDialog, Activity activity, HttpDialogFactory dialogFactory);

    T dialog(boolean showDialog, Activity activity, Dialog dialog);

    T dialog(boolean showDialog, Activity activity);


    T init();

    /**
     * 配置访问地址 全路径或不全都可以
     *
     * @param url 访问地址
     */
    T url(String url);

    /**
     * 获取访问地址
     */
    String getUrl();

    /**
     * 获取访问地址 后拼接参数
     */
    String getQueryUrl();

    T setType(Type type);

    Type getType();

    T contentType(String contentType);

    String getContentType();

    T method(String method);

    String getMethod();

    boolean isDownload();

    boolean isGet();

    //<editor-fold desc="Download">

    /**
     * 添加下载监听
     *
     * @param listener 监听
     */
    T addDownloadListener(ProgressListener listener);

    /**
     * 获取下载监听
     */
    HttpTag.DownloadListeners downloadProgressListeners();
    //</editor-fold>

    //<editor-fold desc="Timeout">

    /**
     * 请求次数
     *
     * @param retryCount 请求次数
     */
    T retryCount(int retryCount);

    /**
     * 请求次数
     */
    int getRetryCount();

    int getConnectTimeout();

    int getReadTimeout();

    int getWriteTimeout();

    T timeout(int connectTimeout, int readTimeout, int writeTimeout);
    //</editor-fold>

    //<editor-fold desc="Param">
    T param(String k, Object v);

    T param(String k, Object v, boolean enabled);

    T paramAll(Map<String, Object> params);

    T paramAll(List<HttpParam> params);

    List<HttpParam> getBodyParameters();
    //</editor-fold>

    //<editor-fold desc="Query">
    T query(String k, Object v);

    T query(String k, Object v, boolean enabled);

    T addQueryAll(Map<String, Object> query);

    T addQueryAll(List<HttpParam> query);

    List<HttpParam> getQueryParameters();
    //</editor-fold>

    //<editor-fold desc="Header">
    ///添加header
    T header(String k, String v);

    ///添加header
    T addHeaderAll(Map<String, String> header);

    Map<String, String> getHeader();

    ///移除header
    T removeHeader(String k);
    //</editor-fold>

    //<editor-fold desc="Interceptor">
    List<HttpInterceptor.RequestInterceptor> getRequestInterceptor();

    T interceptor(HttpInterceptor.RequestInterceptor requestInterceptor);

    List<HttpInterceptor.ResponseInterceptor> getResponseInterceptor();

    T interceptor(HttpInterceptor.ResponseInterceptor responseInterceptor);

    List<HttpInterceptor.ExceptionInterceptor> getExceptionInterceptor();

    T interceptor(HttpInterceptor.ExceptionInterceptor exceptionInterceptor);

    HttpConvert<?> getHttpConvert();

    T convert(HttpConvert<?> httpConvert);
    //</editor-fold>

    //<editor-fold desc="Request">
    <D> D execute() throws IOException;

    <D> D execute(Type type) throws IOException;

    default <D> D execute(Type rawType, Type... typeArguments) throws IOException {
        return execute(TypeUtil.typeOf(rawType, typeArguments));
    }

    <D> void enqueue(HttpCallback<D> callback);

    default String asString() throws IOException {
        return this.<String>execute(String.class);
    }

    default Integer asInteger() throws IOException {
        return this.<Integer>execute(Integer.class);
    }

    default Boolean asBoolean() throws IOException {
        return this.<Boolean>execute(Boolean.class);
    }

    default Long asLong() throws IOException {
        return this.<Long>execute(Long.class);
    }

    default Double asDouble() throws IOException {
        return this.<Double>execute(Double.class);
    }

    default Float asFloat() throws IOException {
        return this.<Float>execute(Float.class);
    }

    //</editor-fold>
}
